﻿#include"XQPandas.h"
#include<QFile>
#include<QTextCodec>
#include<QTextStream>
#include<QDebug>
const XQPandasItem& XQPandas::at(qsizetype i) const
{
	return m_data[i];
}

qsizetype XQPandas::size() const
{
	return m_data.size();
}

QList<XQPandasItem>::iterator XQPandas::begin()
{
	return m_data.begin();
}

QList<XQPandasItem>::const_iterator XQPandas::begin() const
{
	return m_data.begin();
}

QList<XQPandasItem>::reverse_iterator XQPandas::rbegin()
{
	return m_data.rbegin();
}

QList<XQPandasItem>::const_reverse_iterator XQPandas::rbegin() const
{
	return m_data.rbegin();
}

QList<XQPandasItem>::iterator XQPandas::end()
{
	return m_data.end();
}

QList<XQPandasItem>::const_iterator XQPandas::end() const
{
	return m_data.end();
}

QList<XQPandasItem>::reverse_iterator XQPandas::rend()
{
	return m_data.rend();
}

QList<XQPandasItem>::const_reverse_iterator XQPandas::rend() const
{
	return m_data.rend();
}

XQPandasItem& XQPandas::front()
{
	return m_data.front();
}

const XQPandasItem& XQPandas::front() const
{
	return m_data.front();
}

XQPandasItem& XQPandas::back()
{
	return m_data.back();
}

const XQPandasItem& XQPandas::back() const
{
	return m_data.back();
}


XQPandas::~XQPandas()
{
	if(m_file_write)
		m_file_write->deleteLater();
	if(m_file_read)
		m_file_read->deleteLater();
}

QStringList XQPandas::title() const
{
	auto indexs = m_titleText.keys();
	std::sort(indexs.begin(),indexs.end());
	QStringList list;
	for (auto& nSel:indexs)
	{
		list << m_titleText[nSel];
	}
	return list;
}

bool XQPandas::isEmpty() const
{
	return m_data.isEmpty();
}

QString XQPandas::info() const
{
	return m_info;
}

void XQPandas::read_csv(const QString& text, int skipRow, bool title)
{
	m_info.clear();
	auto textRow=text.split("\n");//分割成每行
	int nSel = 0;//当前索引行
	if (skipRow!=0)//需要跳过行
	{
		for (size_t i = 0; i < skipRow; i++)
		{
			m_info += textRow[i];
		}
		nSel += skipRow;
	}
	if (title)//有标题行
	{
		auto column = textRow[nSel].split(",");//分割成每列
		for (size_t i = 0; i < column.size(); i++)
		{
			m_titleIndex[column[i]] = i;
			m_titleText[i] = column[i];
		}
		nSel++;
	}
	else
	{
		auto column = textRow[nSel].split(",");//分割成每列
		for (size_t i = 0; i < column.size(); i++)
		{
			m_titleIndex[QString::number(i)] = i;
			m_titleText[i] = QString::number(i);
		}
	}
	m_data.clear();
	for (size_t i = nSel; i < textRow.size(); i++)
	{
		//auto column = textRow[nSel].split(",");//分割成每列
		if(!textRow[i].isEmpty())
			m_data << XQPandasItem(textRow[i].split(","),&m_titleIndex);//分割成每列
	}
	//qInfo() << textRow;
}

void XQPandas::read_csv(int skipRow, bool title)
{
	read_csv(m_buff,skipRow,title);
	m_buff.clear();
}

void XQPandas::readfile(const QString& path, const QString& coding)
{
	QTextCodec* codec = QTextCodec::codecForName(coding.toUtf8().data());
	QFile file(path);
	file.open(QFile::ReadOnly | QFile::Text);
	m_buff=codec->toUnicode( file.readAll());
}

void XQPandas::readCsvFile_begin(const QString& path, int skipRow, bool title, const QString& coding)
{
	m_codec= QTextCodec::codecForName(coding.toUtf8().data());
	m_file_read=new QFile (path);
	if (!m_file_read->open(QFile::ReadOnly | QFile::Text))
	{
		m_file_read->deleteLater();
		m_file_read = nullptr;
		return;
	}
	int nSel = 0;//当前索引行
	if (skipRow != 0)//需要跳过行
	{
		for (size_t i = 0; i < skipRow; i++)
		{
			m_info += m_codec->toUnicode(m_file_read->readLine()).trimmed();
		}
		nSel += skipRow;
	}
	if (title)//有标题行
	{
		auto list = m_codec->toUnicode(m_file_read->readLine().trimmed()).split(",");//分割成每列
		for (size_t i = 0; i < list.size(); i++)
		{
			auto &text = list[i];
			m_titleIndex[text] = i;
			m_titleText[i] = text;
		}
		nSel++;
	}
}

bool XQPandas::isReadAtEnd()
{
	if(m_file_read==nullptr)
	return true;
	return m_file_read->atEnd();
}

XQPandasItem XQPandas::readLine()
{
	return XQPandasItem(m_codec->toUnicode(m_file_read->readLine().trimmed()).split(","),&m_titleIndex);
}


void XQPandas::readfile_end()
{
	if (m_file_read)
	{
		m_file_read->close();
		m_file_read->deleteLater();
		m_file_read = nullptr;
	}
}

void XQPandas::writefile(const QString& path)
{
	QFile file(path);
	file.open(QFile::WriteOnly | QFile::Text);
	if(!m_info.isEmpty())
		file.write((info() + "\n").toUtf8());//写入信息
	auto title = this->title();
	if(!title.isEmpty())
		file.write((title.join(",") + "\n").toUtf8());//写入标题
	for (auto &data: m_data)
	{
		file.write((data.toStringList().join(",") + "\n").toUtf8());//写入一行数据
	}
}

void XQPandas::writeCsvFile_begin(const QString& path)
{
	if (m_file_write)
		m_file_write->deleteLater();
	m_file_write= new QFile(path);
	m_file_write->open(QFile::WriteOnly | QFile::Text);
	if (!m_info.isEmpty())
		m_file_write->write((info() + "\n").toUtf8());//写入信息
	auto title = this->title();
	if (!title.isEmpty())
		m_file_write->write((title.join(",") + "\n").toUtf8());//写入标题
}

void XQPandas::writefile_end()
{
	if (m_file_write)
	{
		m_file_write->close();
		m_file_write->deleteLater();
		m_file_write = nullptr;
	}
}

void XQPandas::setTitle(const QStringList& titles)
{
	clearTitle();
	for (size_t i = 0; i < titles.size(); i++)
	{
		m_titleText[i] = titles[i];
		m_titleIndex[titles[i]] = i;
	}
}

void XQPandas::setTitle(int column, const QString& title)
{
	if (column < 0)
		return;
	if (m_titleText.find(column) != m_titleText.end())
		m_titleIndex.remove(m_titleText[column]);
	m_titleText[column] = title;
	m_titleIndex[title] = column;
}

void XQPandas::clearTitle()
{
	m_titleIndex.clear();
	m_titleText.clear();
}

void XQPandas::setInfo(const QString& info)
{
	m_info = info;
}

//void XQPandas::setIndexColumn(int column)
//{
//	if (m_titleText.find(column) == m_titleText.end())
//		return;
//	m_indexColumn = column;
//}
//
//void XQPandas::setIndexColumn(const QString& title)
//{
//	setIndexColumn(m_titleIndex[title]);
//}

void XQPandas::clear()
{
	m_data.clear();
	m_buff.clear();
	clearTitle();
}

XQPandas& XQPandas::operator<<(XQPandasItem&& other)
{
	other.setTitle(&m_titleIndex);
	if (m_file_write)
	{
		m_file_write->write((other.toStringList().join(",") + "\n").toUtf8());//写入一行数据
	}
	else
	{
		m_data.append(other);
	}
	return *this;
}

XQPandas& XQPandas::operator<<(const XQPandasItem& other)
{
	auto o = other;
	o.setTitle(&m_titleIndex);
	if (m_file_write)
	{
		m_file_write->write((o.toStringList().join(",") + "\n").toUtf8());//写入一行数据
	}
	else
	{
		m_data.append(o);
	}
	return *this;
}

XQPandas& XQPandas::operator<<(XQPandas&& other)
{
	m_data.append(other.m_data);
	//m_data.back().setTitle();
	return *this;
}

XQPandas& XQPandas::operator<<(const XQPandas& other)
{
	m_data.append(other.m_data);
	return *this;
}

XQPandasItem& XQPandas::operator[](qsizetype i)
{
	return m_data[i];
}

const XQPandasItem& XQPandas::operator[](qsizetype i) const
{
	return m_data[i];
}
